﻿using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WorkFlowCore.Common.Authentication.JWT;

namespace WorkFlowCore.Common.Authorization.JWT
{
    public class AuthorizationMiddleware
    {
        private readonly RequestDelegate next;

        public AuthorizationMiddleware(RequestDelegate next)
        {
            this.next = next;
        }

        private string GetContextParameter(HttpContext httpContext, string parameterName)
        {
            var value = httpContext.Request.Headers[parameterName].ToString();

            if (string.IsNullOrWhiteSpace(value))
            {
                value = httpContext.Request.Query[parameterName].ToString();
            }
            if (string.IsNullOrWhiteSpace(value))
            {
                try
                {
                    value = httpContext.Request.Form[parameterName].ToString();
                }
                catch (Exception)
                {
                    //
                }
            }
            return value;
        }

        public async Task Invoke(HttpContext context, JWTAuthenticationManager jWTAuthenticationManager,IServiceProvider serviceProvider)
        {
            var appid = GetContextParameter(context, "appid");
            var accessToken = GetContextParameter(context, "access_token");
            if (!string.IsNullOrEmpty(accessToken))
            {
                context.Request.Headers["authorization"] = $"Bearer {accessToken}";
            }

            accessToken = context.Request.Headers["authorization"].ToString();

            //var result = await context.AuthenticateAsync();

            if (!jWTAuthenticationManager.TokenValid(accessToken))
            {
                if (!JWTAuthenticationOptions.AuthenticationEnacted)
                {
                    context.Request.Headers["authorization"] = $"Bearer {jWTAuthenticationManager.GenerateDefaultToken()}";
                }
                else
                {
                    //获取默认认证
                    var customizationVerifyImplements = serviceProvider.GetServices<ICustomizationVerify>();
                    
                    //获取自定义认证插件的认证
                    var customizationVerifyExtensions = serviceProvider.GetService<ICustomizationVerify[]>();

                    var allCustomizationVerifies = (customizationVerifyImplements ?? Array.Empty<ICustomizationVerify>()).Concat((customizationVerifyExtensions ?? Array.Empty<ICustomizationVerify>()));


                    var valid = false;

                    foreach (var _customizationVerify in allCustomizationVerifies)
                    {
                        var verify = _customizationVerify.Verify(new VerifyInput { Context = context, OriginalToken = accessToken, AppId = appid });
                        if (verify.IsValid)
                        {
                            valid = true;
                            accessToken = jWTAuthenticationManager.Login(verify.User, verify.Claims);
                            context.Request.Headers["authorization"] = $"Bearer {accessToken}";
                            break;
                        }
                    }
                    
                    //if (!valid)
                    //{
                    //    context.Request.Headers["authorization"] = string.Empty;
                    //}
                }
            }

            await next(context);

            accessToken = context.Request.Headers["authorization"];
            if(context.AuthenticateAsync().Result.Succeeded)
            {
                if(!jWTAuthenticationManager.TokenValid(accessToken))
                {
                    jWTAuthenticationManager.Login(accessToken, string.Empty);
                }
            }
            else
            {
                jWTAuthenticationManager.Logout(string.Empty);
            }

        }
    }
}
